package com.xiaoyu.base.db;

import com.j256.ormlite.dao.Dao;

import java.sql.SQLException;

import in.srain.cube.concurrent.AppThreads;
import in.srain.cube.concurrent.SimpleTask;
import in.srain.cube.util.CLog;

public abstract class DBCall<ReturnType, ItemType, ID> {

    private static final String TAG = "DBCall";

    private static <ReturnType> ReturnType syncExecute(Class cls, DBCall dbCall) {
        try {
            final Object object = DatabaseHelper.getInstance().getDao(cls);
            Dao dao = null;
            if (object instanceof Dao) {
                dao = (Dao) object;
            }
            if (dao == null) {
                return null;
            }
            return (ReturnType) dbCall.exec(dao);
        } catch (SQLException e) {
            e.printStackTrace();
            CLog.e(TAG, "syncExecute error: %s", e.getSQLState());
        }
        return null;
    }

    private static <ReturnType> void asyncExecute(final Class cls, final DBCall dbCall, final Callback<ReturnType> callback) {
        SimpleTask task = new SimpleTask() {
            ReturnType mData = null;

            @Override
            public void doInBackground() {
                mData = syncExecute(cls, dbCall);
            }

            @Override
            public void onFinish(boolean canceled) {
                if (callback != null) {
                    callback.done(mData);
                }
            }
        };
        AppThreads.runOnDBThread(task);
    }

    protected abstract ReturnType exec(Dao<ItemType, ID> dao) throws SQLException;

    public <ReturnType> ReturnType syncCall(Class cls) {
        return syncExecute(cls, this);
    }

    public <T> void asyncCall(Class cls, Callback<T> callback) {
        asyncExecute(cls, this, callback);
    }

    public void oneWayCall(Class cls, boolean async) {
        if (async) {
            asyncCall(cls, null);
        } else {
            syncCall(cls);
        }
    }

    public interface Callback<T> {
        void done(T data);
    }
}

